#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void* thread1(void* arg){
  printf("i am thread1\n");
  int *p = (int*)malloc(sizeof(int));
  pthread_exit((void*)p);
}

void* thread2(void* arg){
  printf("i am thread2\n");
  double *p = (double*)malloc(sizeof(double));
  return (void*)p;
}

void* thread3(void* arg){
  printf("i am thread3\n");
  while(1){
    printf("i am thread3\n");
    sleep(2);
  }
  return NULL;
}

void* thread4(void* arg){
  printf("i am thread4\n");
  int err =  pthread_cancel(*(pthread_t*)arg);
  if(err != 0){
    fprintf(stderr, "4pthread_cancel %s\n", strerror(err));
  }
  err = pthread_cancel(pthread_self());
  if(err != 0){
    fprintf(stderr, "pthread_cancel %s\n", strerror(err));
  }
  while(1){
    printf("i am thread4\n");
    sleep(2);
  }
  return NULL;
}

int main(){
  pthread_t tid;
  void* ret;
  pthread_create(&tid, NULL, thread1, NULL);
  int err;
  if((err = pthread_join(tid, &ret)) != 0){
    fprintf(stderr, "%s\n", strerror(err));
    exit(0);
  }
  free(ret);
  pthread_create(&tid, NULL, thread2, NULL);
  if((err = pthread_join(tid, &ret)) != 0){
    fprintf(stderr, "%s\n", strerror(err));
    exit(0);
  }
  free(ret);
  pthread_create(&tid, NULL, thread3, NULL);
  pthread_t arg = tid;
  pthread_create(&tid, NULL, thread4, &arg);
  err = pthread_cancel(arg);
  if(err != 0){
    fprintf(stderr, "main pthread_cancel %s\n", strerror(err));
  }
  pthread_join(arg, &ret);
  if(ret == PTHREAD_CANCELED){
    printf("PTHREAD_CANCELED3\n");
  }
  pthread_cancel(tid);
  pthread_join(tid, &ret);
  if(ret == PTHREAD_CANCELED){
    printf("PTHREAD_CANCELED4\n");
  }
  return 0;
}
